'''
Created on 26/04/2013

@author: mirta
'''
from flask import Blueprint
from flask import flash
from flask import request
from flask import render_template
from flask import redirect
from flask import url_for
from flask import Response
from flask import session
from datetime import date

from app import db
from app.security import permission
from app.security import g

from werkzeug import secure_filename

from app.wtforms.item_forms import ItemBuscar
from app.wtforms.item_forms import ItemCrear
from app.wtforms.item_forms import ElegirFaseForm
from app.wtforms.item_forms import ArchivoForm
from app.wtforms.item_forms import ElegirTipoItem
from app.wtforms.item_forms import F 
from app.wtforms.item_forms import G
from app.wtforms.item_forms import H
from app.wtforms.item_forms import ItemVerHistorial
from app.wtforms.item_forms import SeleccionarVersionItem
from app.wtforms.item_forms import ReversionItem

from app.models.item import Item
from app.models.fase import Fase
from app.models.permiso import Permiso
from app.models.archivo import Archivo
from app.models.tipoItem import TipoItem
from app.models.atributo_item import AtributoItem
from app.models.atributo import Atributo
from app.models.historial import Historial
from app.models.rol import Rol


from app.reportes.item_reporte import ItemReport
from app.reportes.historial_reporte import HistorialReport
from geraldo.generators import PDFGenerator

from app.security import g
from app.security import permission

import os

from flask_wtf import TextField
from app.models import usuario


mod = Blueprint('items', __name__, url_prefix='/item')


@mod.route('/administracion/', methods=['GET', 'POST'])
@permission('ADMINISTRACION_ITEMS')
def administracion_item():
      
    """
        Muestra en pantalla los item que existen en la base de datos.
        
        @param filtros: los filtros segun los cuales se mostraran los items.
        @return: listado de los items segun los filtros indicados.
    """
    proyecto_seleccionado = g.proyecto
    if(proyecto_seleccionado != None):
        form = ItemBuscar(request.form) 
        
        
        nombreFilter = form.nombre.data
        versionFilter = form.version.data
        prioridadFilter = form.prioridad.data
        
        complejidadFilter = form.complejidad.data
        duracionFilter = form.duracion.data
        estadoFilter = form.estado.data
        descripcionFilter = form.descripcion.data
        faseFilter = form.fase.data
        
        if(nombreFilter == None):
            nombreFilter = ''         
        if(versionFilter == None):  
            versionFilter = ''
        if(prioridadFilter == None):  
            prioridadFilter = ''
        
        if(complejidadFilter == None):
            complejidadFilter = '' 
        if(duracionFilter == None):
            duracionFilter = '' 
        if(estadoFilter == None):
            estadoFilter = ''
        if(descripcionFilter == None):
            descripcionFilter = ''
        if(faseFilter == None):
            faseFilter = ''
            
        
        items = Item.query.filter(Item.nombre.like('%' + nombreFilter + '%'), Item.version.like('%' +versionFilter + '%'), Item.prioridad.like('%' +prioridadFilter + '%'), Item.complejidad.like('%' + complejidadFilter+ '%'), Item.duracion.like('%' + duracionFilter+ '%'), Item.estado.like('%' +estadoFilter + '%'), Item.descripcion.like('%' +descripcionFilter + '%')).join(Fase).filter(Fase.proyecto_id == proyecto_seleccionado.id)
        items.all()
        
        
        return render_template('item/administracion_item.html', form = form, items = items) 
    else:
        flash('No tiene permiso para ver esta pagina.')
        return redirect(url_for('acceso.home'))


@mod.route('/crear/<tipo_item>/', methods=['GET', 'POST'])
def crear_item(tipo_item):
    """
        Muestra en pantalla el formulario de creacion de items, valida los datos ingresados por
        el usuario, hace las validaciones de que el nombre del nuevo item no exista en el
        sistema y se hayan ingresado los datos obligatorios. Luego almacena en base de datos.
        @param fase_item: la fase en la que se quiere crear el item
    """
     
    tipoItem = TipoItem.query.filter_by(id = tipo_item).first()
    
    atributos = tipoItem.atributo
    
    for atributo in atributos:       
        setattr(F, atributo.nombre, TextField(atributo.nombre))
   
    fase = tipoItem.fase   
       
    if(verificar_autorizacion_fase(usuario=g.user, fase=fase, permisoRequerido='MODIFICAR')):
        prioridadChoices = (('1', 'Baja'), ('2', 'Normal'), ('3', 'Alta'))        
        
        form = F(request.form)        
        
        form.prioridad.choices = prioridadChoices        
      
        if form.validate_on_submit():
                    
            #obtener los items de la fase
            items = []
            items = Item.query.filter(Item.fase == fase)
            items = items.all()
            
            if(fase.estado != 'Finalizada'):    
                nombre = form.nombre.data
                
                contN = 0         
                # Comparamos que el nombre ingresado por el usuario no sea igual a uno existente
                if items != []:
                    for item in items:
                        if item.nombre == nombre:
                            contN = contN + 1
                                         
                # Si ya existe el nombre, no permitimos la creacion           
                if contN != 0:
                    flash("El nombre del item ya existe dentro de la fase seleccionada, elija otro", 'error-message')
                    # Redirigimos a la pagina de administracion
                    return redirect(url_for('items.crear_item', tipo_item = tipoItem.id))
                
                
                version = '1'                
                posicionPrioridad= int(form.prioridad.data)                
                prioridad = prioridadChoices[posicionPrioridad-1][1]
                costo = int(form.costo.data)            
                complejidad = form.complejidad.data
                duracion = form.duracion.data
                descripcion = form.nombre.data
                observacion = form.nombre.data
            
                items = Item.query.filter_by(fase_id = fase.id)
                fecha_creacion = date.today()
                estado = 'Activo'
                ultimo = 0
                
                for item in items:                
                    if(item.numero > ultimo):
                        ultimo = item.numero                     
                 
                numero = ultimo + 1                
                                          
                item = Item(nombre, version, prioridad, costo, complejidad, duracion, estado, descripcion, observacion, numero, fecha_creacion, fase, tipoItem)
                db.session.add(item)
                
                
                
                bandera = True
                for atributo in atributos:                    
                    if(atributo.tipo == 'Integer'):
                        try:
                           valor_string = getattr(form, atributo.nombre).data
                           valor_int = int(valor_string)
                           atributoItem = AtributoItem(item.id, atributo.id, item.version, getattr(form, atributo.nombre).data )                   
                           db.session.add(atributoItem)
                           
                           
                        except ValueError:
                            flash('El valor introducido no es un entero')
                            flash('No se puede guardar el item')
                            bandera = False
                    else:
                        atributoItem = AtributoItem(item.id, atributo.id, item.version, getattr(form, atributo.nombre).data )                   
                        db.session.add(atributoItem)
                        
                        
                        
                if(bandera):                   
                    db.session.commit()
                    for atributo in atributos:                    
                        atributoItem = AtributoItem(item.id, atributo.id, item.version, getattr(form, atributo.nombre).data )                   
                        db.session.add(atributoItem)                    
                           
                    db.session.commit()                
                        
                    flash('El item ha sido registrado con exito')    
                    if(fase.estado == 'Pendiente'):
                        fase.estado = 'Activa'
                        db.session.add(fase)
                        db.session.commit()
                    
                return redirect(url_for('items.administracion_item'))
            else:
                flash('La fase ya ha sido finalizada, no se pueden agregar items')
    else:
        flash('No tiene permisos para crear items dentro de la fase seleccionada') 
        return redirect(url_for('items.administracion_item'))
        
             
    return render_template("item/crear_item.html", form =  form, atributos = atributos)
    

@mod.route('/seleccionar_fase/', methods=['GET', 'POST'])
def seleccionar_fase():
    """
        Muestra en pantalla las fases relacionadas a un proyecto. El usuario selecciona la fase 
        en la cual quiere crear el item
    """
    form = ElegirFaseForm(request.form)
        
    proyecto_login = g.proyecto
    fases = proyecto_login.fases
    
    return render_template("item/seleccionar_fase.html", form =  form, fases = fases)


@mod.route('/seleccionar_tipo_item/<fase_item>/', methods=['GET', 'POST'])
def seleccionar_tipo_item(fase_item):
    
    """
        Muestra en pantalla los tipos de items relacionados a una fase. El usuario selecciona el tipo de item
       con el cual desea asociar el item
       @param fase_item: la fase donde se desea crear el item 
    """
    
    form = ElegirTipoItem(request.form)
    fase = Fase.query.filter_by(id = fase_item).first()    
    tiposItems = fase.fase
   

    #return redirect(url_for('items.administracion_item'))
    return render_template("item/seleccionar_tipo_item.html", form = form, tiposItems = tiposItems)





@mod.route('/consultar/<item_id>/', methods = ['GET', 'POST'])
def consultar_item(item_id):
    """
        Muestra en pantalla los datos de un item
        
        @param item_id: id del item que se desea consultar.
    """
   
         
    item_seleccionado = Item.query.filter_by(id = item_id).first()
    
    fase = item_seleccionado.fase

    if(verificar_autorizacion_fase(usuario=g.user, fase=fase, permisoRequerido='MODIFICAR')):

        atributosItem = AtributoItem.query.filter_by(id_item = item_seleccionado.id, version = item_seleccionado.version).all()
        
        if(atributosItem != None):
            
            for atributoItem in atributosItem:
                atributo = Atributo.query.filter_by(id = atributoItem.id_atributo).first()
                setattr(G, atributo.nombre, TextField(atributo.nombre))
           
        
            
        form = G(request.form)
        if(atributosItem != None):
            for atributoItem in atributosItem:
                atributo = Atributo.query.filter_by(id = atributoItem.id_atributo).first()
                getattr(form, atributo.nombre).data = atributoItem.valor       
    
            
        form.nombre.data = item_seleccionado.nombre
        form.complejidad.data = item_seleccionado.complejidad
        form.costo.data = item_seleccionado.costo
        form.descripcion.data = item_seleccionado.descripcion
        form.observacion.data = item_seleccionado.observacion
        form.estado.data = item_seleccionado.estado
        form.duracion.data = item_seleccionado.duracion
        form.fecha_creacion.data = item_seleccionado.fecha_creacion
        form.prioridad.data = item_seleccionado.prioridad
        form.tipo.data = item_seleccionado.tipo.nombre
        form.version.data = item_seleccionado.version
      
        return render_template("item/consultar_item.html", form=form)
    else:
        flash('No tiene permisos para consultar items dentro de la fase seleccionada') 
        return redirect(url_for('items.administracion_item'))            

    


@mod.route('/modificar/<item_id>/', methods = ['GET', 'POST'])
def modificar_item(item_id):
    """
        Muestra en pantalla los datos para la modificacion de un item
        
        @param item: id del item que se desea modificar.
    """
   
         
    item_seleccionado = Item.query.filter_by(id = item_id).first()
    iditem = item_seleccionado.id
    fase = item_seleccionado.fase
    if(fase.estado != 'Finalizada' and item_seleccionado.estado == 'Activo'):    
    
        if(verificar_autorizacion_fase(usuario=g.user, fase=fase, permisoRequerido='MODIFICAR')):
    
        
            atributosItem = AtributoItem.query.filter_by(id_item = item_seleccionado.id, version = item_seleccionado.version).all()
            
            
            
            prioridadChoices = (('1', 'Baja'), ('2', 'Normal'), ('3', 'Alta'))        
            choicesEstados = (('1','Activo'), ('2', 'Aprobado'), ('3','Bloqueado'), ('4','Revision'), ('5','Eliminado'))
            
            
            if(atributosItem != None):
                
                for atributoItem in atributosItem:
                    atributo = Atributo.query.filter_by(id = atributoItem.id_atributo).first()
                    setattr(H, atributo.nombre, TextField(atributo.nombre))
               
            
                
            form = H(request.form)
           
             
        
            form.prioridad.choices = prioridadChoices
            form.estado.choices = choicesEstados 
                 
            
            
            #obtener los items de la fase
            #items = []
            items = Item.query.filter(Item.fase == fase)
            items = items.all()
           
            if form.validate_on_submit():
                
                contN = 0         
                # Comparamos que el nombre ingresado por el usuario no sea igual a uno existente
                #if items != []:
                if items != None:
                    for item in items:
                        #if item_seleccionado.id != item.id:
                        
                        if form.nombre.data == item.nombre:
                            contN = contN + 1
                                         
                # Si ya existe el nombre, no permitimos la creacion           
                #if contN != 0:
                
                if (contN != 0 and form.nombre.data != item_seleccionado.nombre):
                    flash("El nombre del item ya existe dentro de la fase seleccionada, elija otro", 'error-message')
                    # Redirigimos a la pagina de administracion
                    return redirect(url_for('items.modificar_item', item_id = iditem))            
                   
                historial_item = Historial()
                historial_item.setAntecesor(item_seleccionado.antecesor_id)
                historial_item.setComplejidad(item_seleccionado.complejidad)
                historial_item.setCosto(item_seleccionado.costo)
                historial_item.setDescripcion(item_seleccionado.descripcion)
                historial_item.setDuracion(item_seleccionado.duracion)
                historial_item.setEstado(item_seleccionado.estado)
                historial_item.setFase(item_seleccionado.fase)
                historial_item.setFechaCreacion(item_seleccionado.fecha_creacion)
                historial_item.setFechaModificacion(date.today())
                historial_item.setItemId(item_seleccionado.id)
                historial_item.setLb(item_seleccionado.linea_base)
                historial_item.setNombre(item_seleccionado.nombre)
                historial_item.setNumero(item_seleccionado.numero)
                historial_item.setObservacion(item_seleccionado.observacion)
                historial_item.setPadre(item_seleccionado.padre_id)
                historial_item.setPrioridad(item_seleccionado.prioridad)
                historial_item.setVersion(item_seleccionado.version)                
                                  
                                  
                
                item_seleccionado.nombre = form.nombre.data                 
                version_int = int(item_seleccionado.version)
                version_int = version_int + 1                
                item_seleccionado.version = str(version_int)
                                                      
                posicionPrioridad= int(form.prioridad.data)                
                item_seleccionado.prioridad = prioridadChoices[posicionPrioridad-1][1] 
                                           
                item_seleccionado.costo = int(form.costo.data)            
                item_seleccionado.complejidad = form.complejidad.data
                item_seleccionado.duracion = form.duracion.data
                            
                posicionEstado = int(form.estado.data)    
                item_seleccionado.estado = choicesEstados[posicionEstado-1][1]
                                       
                item_seleccionado.descripcion = form.descripcion.data
                item_seleccionado.observacion = form.observacion.data
                                        
                                                      
                db.session.add(item_seleccionado)
                db.session.add(historial_item)
                    
                atributos = item_seleccionado.tipo.atributo        
                bandera = True
                for atributo in atributos:                    
                    if(atributo.tipo == 'Integer'):
                        try:
                            valor_string = getattr(form, atributo.nombre).data
                            valor_int = int(valor_string)                          
                               
                               
                        except ValueError:
                            flash('El valor introducido no es un entero')
                            flash('No se pueden actualizar el item')
                            bandera = False
                       
                            
                            
                            
                if(bandera):                   
                    db.session.commit()
                                
                    atributos = item_seleccionado.tipo.atributo
                    for atributo in atributos:
                        atributoItem = AtributoItem(item_seleccionado.id, atributo.id, item_seleccionado.version, getattr(form, atributo.nombre).data )
                        db.session.add(atributoItem)
                        db.session.commit()
                            
                        flash('El item ha sido modificado con exito')
                        return redirect(url_for('items.administracion_item'))
                   
            form.nombre.data = item_seleccionado.nombre
            form.complejidad.data = item_seleccionado.complejidad
            form.costo.data = item_seleccionado.costo
            form.descripcion.data = item_seleccionado.descripcion
            form.observacion.data = item_seleccionado.observacion
            form.duracion.data = item_seleccionado.duracion
          
            
            if(atributosItem != None):
                for atributoItem in atributosItem:
                    atributo = Atributo.query.filter_by(id = atributoItem.id_atributo).first()
                    getattr(form, atributo.nombre).data = atributoItem.valor  
          
            return render_template("item/modificar_item.html", form=form)
        else:
            flash('No tiene permisos para modificar items dentro de la fase seleccionada') 
            return redirect(url_for('items.administracion_item'))  
    else:
            flash('Verifique que el estado de la fase y el item sean los necesarios')  
            return redirect(url_for('items.administracion_item'))          




@mod.route('/eliminar/<item>/', methods=['GET', 'POST'])
def eliminar_item(item):
    """
        Muestra en pantalla el formulario de eliminacion de items, se pide la confimacion del usuario 
        y se elimina el item.
        
        @param item: id del item que se desea eliminar.
    """
    
    itemSeleccionado = Item.query.filter_by(id = item).first()
        
    itemsFase = Item.query.filter(Item.fase_id == itemSeleccionado.fase_id, Item.estado != 'Eliminado' ).all()
    
        # Obtenemos la fase del item seleccionado
    fase = Fase.query.filter_by(id = itemSeleccionado.fase_id).first()    
    
    # Verificamos si el usuario tiene permisos para modificar los items de la fases
    if(verificar_autorizacion_fase(usuario=g.user, fase=fase, permisoRequerido='MODIFICAR')):
        for itemFase in itemsFase:
            if(itemFase.numero > itemSeleccionado.numero):
                itemFase.numero = itemFase.numero - 1
                db.session.add(itemFase)
        
        
        if(itemSeleccionado.estado == 'Activo'or  itemSeleccionado.estado == 'Revision' ):
            
            itemsHijos = Item.query.filter_by(padre_id = item).all()
            for itemHijo in itemsHijos:
                itemHijo.estado = 'Revision'
                db.session.add(itemHijo)
                
            itemsSucesores = Item.query.filter_by(antecesor_id = item).all()
            for itemSucesor in itemsSucesores:
                itemSucesor.estado = 'Revision'
                db.session.add(itemSucesor)
            
            itemSeleccionado.estado = 'Eliminado'
            db.session.add(itemSeleccionado)
            
            db.session.commit()
            
            itemsFase = Item.query.filter(Item.fase_id == itemSeleccionado.fase_id, Item.estado != 'Eliminado' ).all()
            
            
                   
            if (len(itemsFase) == 0):               
                fase.estado = 'Pendiente'
                db.session.add(fase)
                db.session.commit()
                
            flash('El item se ha eliminado exitosamente')    
            
        else:
           
            flash('El item no puede ser eliminado')
    else:
        flash('No tiene permisos para crear items dentro de la fase seleccionada') 
        return redirect(url_for('items.administracion_item'))
            
 
            
    return redirect(url_for('items.administracion_item'))
 
 
 
 
@mod.route('/revivir/<item>/', methods=['GET', 'POST'])
def revivir_item(item):
   
    
    itemSeleccionado = Item.query.filter_by(id = item).first()
        
    #Obtenemos la fase del item seleccionado
    fase = Fase.query.filter_by(id = itemSeleccionado.fase_id).first()    
    
    # Verificamos si el usuario tiene permisos para modificar los items de la fases
    if(verificar_autorizacion_fase(usuario=g.user, fase=fase, permisoRequerido='MODIFICAR')):
        if(fase.estado != 'Finalizada'):
            if(itemSeleccionado.estado == 'Eliminado'):
                
               antecesor_id = itemSeleccionado.antecesor_id
               if(antecesor_id != None):               
                   antecesor = Item.query.filter_by(id = antecesor_id).first()
               else:
                   antecesor = None
                    
               padre_id = itemSeleccionado.padre_id     
               if(padre_id != None):              
                    padre = Item.query.filter_by(id = padre_id).first()
               else:
                    padre = None
               
               
               antecesor_bandera = False
               padre_bandera =  False
               
               if(antecesor != None):
                   if(antecesor.estado != 'Eliminado'):
                       antecesor_bandera = True
               else:
                     antecesor_bandera = True
            
               if(padre != None):
                   if(padre.estado != 'Eliminado'):
                       padre_bandera = True
               else:
                     padre_bandera = True
                     
                     
               historial_item = Historial()
               historial_item.setAntecesor(itemSeleccionado.antecesor_id)
               historial_item.setComplejidad(itemSeleccionado.complejidad)
               historial_item.setCosto(itemSeleccionado.costo)
               historial_item.setDescripcion(itemSeleccionado.descripcion)
               historial_item.setDuracion(itemSeleccionado.duracion)
               historial_item.setEstado(itemSeleccionado.estado)
               historial_item.setFase(itemSeleccionado.fase)
               historial_item.setFechaCreacion(itemSeleccionado.fecha_creacion)
               historial_item.setFechaModificacion(date.today())
               historial_item.setItemId(itemSeleccionado.id)
               historial_item.setLb(itemSeleccionado.linea_base)
               historial_item.setNombre(itemSeleccionado.nombre)
               historial_item.setNumero(itemSeleccionado.numero)
               historial_item.setObservacion(itemSeleccionado.observacion)
               historial_item.setPadre(itemSeleccionado.padre_id)
               historial_item.setPrioridad(itemSeleccionado.prioridad)
               historial_item.setVersion(itemSeleccionado.version)       


               atributos = itemSeleccionado.tipo.atributo
               for atributo in atributos: 
                    atributoItem = AtributoItem.query.filter_by(id_item=itemSeleccionado.id, id_atributo = atributo.id, version = itemSeleccionado.version).first()                                   
                    atributoItemNuevo = AtributoItem(atributoItem.id_item, atributoItem.id_atributo, atributoItem.version + 1, atributoItem.valor )                   
                    db.session.add(atributoItemNuevo)
                    
                    
               if(padre_bandera and antecesor_bandera):
                   itemSeleccionado.estado = 'Activo'
                   version_int = int(itemSeleccionado.version)
                   version_int = version_int + 1                
                   itemSeleccionado.version = str(version_int)
                   mensaje = 'Se ha revivido el item exitosamente'
               else:
                   itemSeleccionado.estado = 'Revision'
                   version_int = int(itemSeleccionado.version)
                   version_int = version_int + 1                
                   itemSeleccionado.version = str(version_int)
                   mensaje = 'Se ha revivido el item con conflictos en sus relaciones, favor verificar las mismas'
            
               db.session.add(itemSeleccionado)
               db.session.add(historial_item)
               db.session.commit()
               flash(mensaje) 
               return redirect(url_for('items.administracion_item'))    
             
            else:                
                flash('El item no esta eliminado, por lo tanto no puede ser revivido') 
                return redirect(url_for('items.administracion_item'))
        else:                
                flash('La fase del item seleccionado ya esta finalizada, no se pueden realizar cambios') 
                return redirect(url_for('items.administracion_item'))
    else:
        flash('No tiene permisos para crear items dentro de la fase seleccionada') 
        return redirect(url_for('items.administracion_item'))
            
 
            
    return redirect(url_for('items.administracion_item'))


@mod.route('/adjuntar/<item>/', methods=['GET', 'POST'])
def adjuntar_archivo(item):
    """
        Muestra en pantalla el formulario para adjuntar archivos a un item.
        
        @param item: id del item al cual se desea adjuntar el archivo.
    """
    
    form = ArchivoForm()
    item_seleccionado = Item.query.filter_by(id = item).first()
    
    fase = Fase.query.filter_by(id = item_seleccionado.fase_id).first()    
    
    # Verificamos si el usuario tiene permisos para modificar los items de la fases
    if(verificar_autorizacion_fase(usuario=g.user, fase=fase, permisoRequerido='MODIFICAR')):
    
        if request.method == 'GET':
            return render_template('item/adjuntar_archivo.html', form = form, item = item_seleccionado)
        else:
            filename = secure_filename(form.archivo.data.filename)
            file_data = form.archivo.data.read()
            file_tipo = form.archivo.data.mimetype
            #gger.info(form.archivo.data)
            #current_app.logger.info(file_data)
            archivo = Archivo(filename, file_data, file_tipo)
            db.session.add(archivo)
            item_seleccionado.add_archivo(archivo)
            db.session.add(item_seleccionado)
            db.session.commit()
            flash(u'Archivo cargado exitosamente, {0}'.format(filename))
            return render_template('item/adjuntar_archivo.html', form = form, item = item_seleccionado)
            #print filename
            #show_the_login_form()
    else:
        flash('No tiene permisos para modificar items dentro de la fase seleccionada') 
        return redirect(url_for('items.administracion_item'))
    
    return redirect(url_for('items.administracion_item'))


@mod.route('/bajar/<archivo>/')
def bajar_archivo(archivo):
    """
        @param archivo: id del arhivo que se desea descargar
    """
    a_bajar = Archivo.query.filter_by(id = archivo).first()
    results = a_bajar.datos
    generator = (cell for row in results
                    for cell in row)
    #flash(u'Bajando archivo: {0}'.format(a_bajar.nombre))
    return Response(generator,
                       mimetype=a_bajar.tipo,
                       headers={"Content-Disposition":
                                    "attachment;filename={0}".format(a_bajar.nombre)})

@mod.route('/eliminar_archivo/<item>/<archivo>/')
def eliminar_archivo(item, archivo):
    """
        Muestra en pantalla el formulario para la eliminacion archivos a de item.
        
        @param item: id del item al cual se desea eliminar el archivo.
        @param archivo: id del archivo que se desea eliminar
    """
    item_seleccionado = Item.query.filter_by(id = item).first()
    
    fase = Fase.query.filter_by(id = item_seleccionado.fase_id).first()    
    
    # Verificamos si el usuario tiene permisos para modificar los items de la fases
    if(verificar_autorizacion_fase(usuario=g.user, fase=fase, permisoRequerido='MODIFICAR')):
    
        a_borrar = Archivo.query.filter_by(id = archivo).first()
        nombre = a_borrar.nombre
        db.session.delete(a_borrar)
        db.session.commit()
        flash(u'Archivo eliminado correctamente: {0}'.format(nombre))
        return redirect(url_for('items.adjuntar_archivo', item=item))
    
    else:
        flash('No tiene permisos para modificar items dentro de la fase seleccionada') 
        return redirect(url_for('items.administracion_item'))
    
    return redirect(url_for('items.administracion_item'))
    


@mod.route('/historial/<item_id>/', methods = ['GET', 'POST'])
def historial_item(item_id):
   
         
    item_seleccionado = Item.query.filter_by(id = item_id).first()
    fase = item_seleccionado.fase
    #obtenemos el formulario
    form = ItemVerHistorial(request.form)
    if(verificar_autorizacion_fase(usuario=g.user, fase=fase, permisoRequerido='MODIFICAR')):
        if(item_seleccionado.estado != None):           
            
            #obtenemos el historial del item seleccionado
            historial = Historial.query.filter(Historial.id_item == item_seleccionado.id)
            estados_item=[]
            datos_item=[]
            desc_item=[]
            antec_item=[]
            padre_item=[]
            for histItem in historial:
                if (histItem != None):
                    estados_item.append((histItem.id,histItem.version +"  "+histItem.estado +"  "+ str(histItem.fecha_creacion) +"  "+ str(histItem.fecha_modificacion) ))
                    
                    if(histItem.prioridad == None or histItem.prioridad == ''):
                        prioridad="Sin datos en prioridad"
                    else:
                        prioridad=histItem.prioridad
                        
                    if(str(histItem.costo) == None or str(histItem.costo) == ''):
                        costo="Sin datos en costo"
                    else:
                        costo = str(histItem.costo)
                        
                    if(histItem.complejidad == None or histItem.complejidad== ''):
                        complejidad="Sin datos en complejidad"
                    else:
                        complejidad=histItem.complejidad
                    
                    datos_item.append((histItem.id,histItem.version +"  "+prioridad+" "+costo+"  "+complejidad) )
                   
                    if(histItem.descripcion == None or histItem.descripcion == ''):
                        descripcion="Sin descripciones"
                    else:
                        descripcion=histItem.descripcion
                        
                    if(histItem.observacion == None or histItem.observacion == ''):
                        observacion="Sin observaciones"
                    else:
                        observacion = histItem.observacion
                    
                    desc_item.append((histItem.id,histItem.version +" "+descripcion+" "+ observacion ))
                    
                    antecesor_id=histItem.antecesor_id
                    if(antecesor_id != None):
                        antecesor = Item.query.filter_by(id = antecesor_id).first()
                    else:
                        antecesor = "Sin antecesores"
                    
                    padre_id=histItem.padre_id
                    if(padre_id != None):
                        padre = Item.query.filter_by(id = padre_id).first()
                    else:
                        padre = "Sin padres"
                    
                    antec_item.append((histItem.id,histItem.version +" "+ antecesor))
                    padre_item.append((histItem.id,histItem.version +" "+ padre))
                    
                    
            
            form.nombre.data = item_seleccionado.nombre
            form.estados.choices = estados_item
            form.datos.choices = datos_item
            form.descripcion.choices=desc_item
            form.antecesores.choices = antec_item
            form.padres.choices = padre_item
            
            if form.validate_on_submit(): 
                #Cuando el usuario presiona aceptar, redirigimos a la pagina de administracion de fases
                return redirect(url_for('items.administracion_item'))        
            #return render_template('item/historial_item.html', form = form, 
            #                  item_id = item_seleccionado.id)
            return render_template('item/historial_item.html', items=historial)
            
        else:
            flash('El item seleccionado no se encuentra con estado Activo') 
            return redirect(url_for('items.administracion_item'))
    else:
        flash('No tiene permisos para consultar el historial de items dentro de la fase seleccionada') 
        return redirect(url_for('items.administracion_item'))    


@mod.route('/seleccionar/<item>/', methods=['GET', 'POST'])
def seleccionar_version(item):
    """
    Muestra en pantalla las versiones de los items de una fase.
    """
    
    #obtenemos el item seleccionado
    item_seleccionado = Item.query.filter_by(id=item).first()  
    #obtenemos el historial del item seleccionado
    historial = Historial.query.filter(Historial.id_item == item_seleccionado.id)
    # Obtenemos la fase del item seleccionado
    fase = Fase.query.filter_by(id = item_seleccionado.fase_id).first()  
      
    
    # Verificamos si el usuario tiene permisos para modificar los items de la fases
    if(verificar_autorizacion_fase(usuario=g.user, fase=fase, permisoRequerido='MODIFICAR')):
        if(fase.estado != 'Finalizada'): 
            if (item_seleccionado.estado == 'Activo'):
                # Obtenemos el formulario para listar las versiones de los items
                form = SeleccionarVersionItem(request.form) 
                #obtenemos todas las versiones del item seleccionado
                lista_versiones=[]
                for version in historial:
                    lista_versiones.append((version.id,version.version))
                
                # Asignamos esa tupla de versiones de items a la lista que va a ser visualizada  
                form.versiones.choices = lista_versiones
                form.item.data = item_seleccionado.nombre
                
                if form.validate_on_submit():
                    session['version_id'] = form.versiones.data
                    return redirect(url_for('items.revertir_item'))       
                     
                return render_template('item/seleccionar_version.html', form = form)
                
            else:                
                flash('El item seleccionado no se encuentra con estado Activo.') 
                return redirect(url_for('items.administracion_item'))
        else:                
            flash('La fase del item seleccionado ya esta finalizada, no se pueden realizar cambios') 
            return redirect(url_for('items.administracion_item'))
    else:
        flash('No tiene permisos para revertir items dentro de la fase seleccionada') 
        return redirect(url_for('items.administracion_item'))




@mod.route('/revertir/', methods=['GET', 'POST'])
def revertir_item():
   
    #obtenemos el historial de la version seleccionada
    id_version = session['version_id']
    version_seleccionada = Historial.query.filter_by(id = id_version[0]).first()
    
    #obtenemos el item de la version seleccionada
    item_actual = Item.query.filter_by(id=version_seleccionada.id_item).first()
    item = item_actual
    
    # Obtenemos el formulario para revertir items
    form = ReversionItem(request.form)
    
    if(version_seleccionada.estado != 'Eliminado'):
        if form.validate_on_submit():                                         
            #almacenamos los valores del item actual
            historial_item = Historial()
            historial_item.setAntecesor(item_actual.antecesor_id)
            historial_item.setComplejidad(item_actual.complejidad)
            historial_item.setCosto(item_actual.costo)
            historial_item.setDescripcion(item_actual.descripcion)
            historial_item.setDuracion(item_actual.duracion)
            historial_item.setEstado(item_actual.estado)
            historial_item.setFase(item_actual.fase)
            historial_item.setFechaCreacion(item_actual.fecha_creacion)
            historial_item.setFechaModificacion(date.today())
            historial_item.setItemId(item_actual.id)
            historial_item.setLb(item_actual.linea_base)
            historial_item.setNombre(item_actual.nombre)
            historial_item.setNumero(item_actual.numero)
            historial_item.setObservacion(item_actual.observacion)
            historial_item.setPadre(item_actual.padre_id)
            historial_item.setPrioridad(item_actual.prioridad)
            historial_item.setVersion(item_actual.version)                  
                         
            db.session.add(historial_item)
            db.session.commit()
            
            atributos = item_actual.tipo.atributo
            for atributo in atributos: 
                atributoItem = AtributoItem.query.filter_by(id_item=item_actual.id, id_atributo = atributo.id, version = item_actual.version).first()                                   
                atributoItemNuevo = AtributoItem(atributoItem.id_item, atributoItem.id_atributo, atributoItem.version + 1, atributoItem.valor )                   
                db.session.add(atributoItemNuevo)
            
                        
            #obtenemos la nueva version para el item               
            version_int = int(item_actual.version)
            version_int = version_int + 1                                   
                  
            #verificamos los estados de los antecesores y padres de la version seleccionada           
            antecesor_id = version_seleccionada.antecesor_id
            if(antecesor_id != None):               
                antecesor = Item.query.filter_by(id = antecesor_id).first()
            else:
                antecesor = None
                        
            padre_id = version_seleccionada.padre_id  
            if(padre_id != None):              
                padre = Item.query.filter_by(id = padre_id).first()
            else:
                padre = None
                   
            antecesor_bandera = False
            padre_bandera =  False
                       
            if(antecesor != None):
                if(antecesor.estado != 'Eliminado'):
                    antecesor_bandera = True
                else:
                    antecesor_bandera = True
                
            if(padre != None):
                if(padre.estado != 'Eliminado'):
                    padre_bandera = True
                else:
                    padre_bandera = True
                             
            if(padre_bandera and antecesor_bandera):
                estado = 'Activo'
            else:
                estado = 'Revision'
                
            #cargamos los datos del historial al item     
            item_actual.version = version_int
            if antecesor!= None:
                item_actual.antecesor_id = antecesor
            if padre!= None:
                item_actual.padre_id = padre
                
            item_actual.complejidad = version_seleccionada.complejidad
            item_actual.costo = version_seleccionada.costo
            item_actual.descripcion = version_seleccionada.descripcion
            item_actual.duracion = version_seleccionada.duracion
            item_actual.estado = estado
            item_actual.fecha_creacion = version_seleccionada.fecha_creacion
            item_actual.prioridad = version_seleccionada.prioridad
            item_actual.observacion = version_seleccionada.observacion
            item_actual.numero = version_seleccionada.numero 
            
     
            db.session.add(item_actual)
            db.session.commit()
            flash('El item fue actualizado a la nueva version con exito.')
            return redirect(url_for('items.administracion_item'))    
             
    else:                
        flash('La version seleccionada se encuentra con estado Eliminado.') 
        return redirect(url_for('items.administracion_item'))
            
    # Mostramos en el formulario los datos actuales item seleccionado
    form.nombre.data = version_seleccionada.nombre
    form.complejidad.data = version_seleccionada.complejidad
    form.prioridad.data = version_seleccionada.prioridad
    form.costo.data = version_seleccionada.costo
    form.duracion.data = version_seleccionada.duracion
   
    
    return render_template('item/revertir_item.html', form = form)        
 

@mod.route('/reporte_item/', methods=['GET', 'POST'])
def reporte_item():
    """
        Genera un pdf con los items del proyecto, agrupados por fase
    """
    
    proyecto = g.proyecto    
    idList = []
    fases = proyecto.fases
    for fase in fases:        
        idList.append(fase.id)
        
    report = ItemReport(Item.query.filter(Item.fase_id.in_(idList)).order_by(Item.fase_id, Item.numero).all())

    cur_dir = os.path.dirname(os.path.abspath(__file__))
    reporte_dir = cur_dir + '/pdf'
    
    nombre = 'reporte_item.pdf'
    #-------------------------------- if reporte_dir.isfile('reporte_item.pdf'):
        #----------------------------------------- nombre = 'reporte_item_2.pdf'
        
    report.generate_by(PDFGenerator, filename=os.path.join(reporte_dir , nombre))
    ruta = '/usr/bin/gnome-open ' + reporte_dir + '/' + nombre
    os.system(ruta)  
    return redirect(url_for('items.administracion_item'))

@mod.route('/reporte_historial/<item_id>/', methods=['GET', 'POST'])
def reporte_historial(item_id):
    """
        Genera un pdf con los items del proyecto, agrupados por fase
    """
      
    
    
    item_seleccionado = Item.query.filter_by(id = item_id).first()
    fase = item_seleccionado.fase
    #obtenemos el formulario
   
    if(verificar_autorizacion_fase(usuario=g.user, fase=fase, permisoRequerido='MODIFICAR')):
        if(item_seleccionado.estado != None):           
            
            #obtenemos el historial del item seleccionado
            historial = Historial.query.filter(Historial.id_item == item_seleccionado.id)
            report = HistorialReport(historial)

            cur_dir = os.path.dirname(os.path.abspath(__file__))
            reporte_dir = cur_dir + '/pdf'
    
            nombre = 'reporte_historial.pdf'
   
        
            report.generate_by(PDFGenerator, filename=os.path.join(reporte_dir , nombre))
            ruta = '/usr/bin/gnome-open ' + reporte_dir + '/' + nombre
            os.system(ruta) 
            return redirect(url_for('items.administracion_item'))     
            
    else:
        flash('No tiene permisos para consultar el historial de items dentro de la fase seleccionada') 
        return redirect(url_for('items.administracion_item'))    




def verificar_autorizacion_fase(usuario = None, fase = None, permisoRequerido = None):
    
    autorizado = False
 
    permiso = db.session.query(Permiso).filter_by(nombre = permisoRequerido, entidad_id = fase.entidad_id).first()
   
    if(permiso != None):
        for rol in usuario.roles:
            if permiso in rol.permiso:
                autorizado = True
    
    return autorizado
        
        
